package com.mida.app.report.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mida.app.report.enumData.DetailCode;
import com.mida.app.report.service.DetailCodingSystemService;
import com.mida.app.report.service.MdmService;
import com.mida.app.report.service.RequestService;
import com.mida.app.report.utils.DataCenterDateUtil;
import com.mida.app.report.vo.ApntRegistrationForm;
import com.mida.app.report.vo.RequestExamPartsInfo;
import com.mida.app.report.vo.RequestListInfo;
import com.mida.app.report.vo.RequestServiceInfo;
import com.mida.bms.customer.api.PersonOperationApi;
import com.mida.bms.customer.vo.person.PatientInfoVo;
import com.mida.bms.customer.vo.person.PersonInfoConditionVo;
import com.mida.bms.exam.api.ExamBmsApi;
import com.mida.bms.exam.vo.exam.ApntOperateVO;
import com.mida.bms.register.api.RegisterBmsApi;
import com.mida.bms.register.vo.register.ApntRegistrationFormVO;
import com.mida.bms.requestform.api.RequestFormApi;
import com.mida.bms.requestform.request.RequestFormInfo;
import com.mida.bms.requestform.request.RequestListInfoVO;
import com.mida.dms.mdm.vo.provider.BusinessUnitVo;
import com.mida.tool.common.result.ListResult;
import com.mida.tool.common.ret.RespBody;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;

/**
 * @ClassName: RequestServiceImpl
 * @Description: 申请单实现层
 * @Author: wang xiao le
 * @Date: 2021/6/19 11:01
 **/
@Service
@Slf4j
public class RequestServiceImpl implements RequestService {
    @Autowired
    private RequestFormApi requestFormApi;
    @Autowired
    private PersonOperationApi personOperationApi;
    @Autowired
    private RegisterBmsApi registerBmsApi;
    @Autowired
    private ExamBmsApi examBmsApi;
    @Autowired
    private MdmService mdmService;
    @Autowired
    private DetailCodingSystemService detailCodingSystemService;

    private static ConcurrentMap<String, String> soidCacheMap = new ConcurrentHashMap<>();

    /**
     * 查询申请单并获取登记单信息
     * @param request
     * @return
     */
    @Override
    public Page<RequestListInfo> getRequestListInfo(RequestFormInfo request) {
        log.info("开始查询申请单=============================================================: ");
        org.apache.commons.lang3.time.StopWatch stopWatch = org.apache.commons.lang3.time.StopWatch.createStarted();
        List<RequestListInfo> requestListInfoList = new ArrayList<>();

        RespBody<Page<RequestListInfoVO>> requestListInfoRes = requestFormApi.getRequestListInfo(request);

        // FIXME: yutao 2021/8/5 下面的6个map,按理说，不太会变，不用每次请求都调一遍接口。
        List<RequestListInfoVO> requestList = requestListInfoRes.getData().getRecords();
        //就诊场景值集Map
        Map<Long, String> seeTheSceneMap = detailCodingSystemService.getDataSetMapByDetailCode(DetailCode.SEE_THE_SCENE.code, null, false);
        //申请单是否紧急值集Map
        Map<Long, String> emergencysignMap = detailCodingSystemService.getDataSetMapByDetailCode(DetailCode.EMERGENCYSIGN.code, null, false);
        //申请单状态值集Map
        Map<Long, String> requestStatusMap = detailCodingSystemService.getDataSetMapByDetailCode(DetailCode.REQUEST_STATUS.code, null, false);
        //检查类型值集Map
        Map<Long, String> examTypeMap = detailCodingSystemService.getDataSetMapByDetailCode(DetailCode.EXAM_TYPE.code, null, false);
        //检查部位值集Map
        Map<Long, String> examPartsMap = detailCodingSystemService.getDataSetMapByDetailCode(DetailCode.EXAM_PARTS.code, null, false);
        //性别值集Map
        Map<Long, String> genderMap = detailCodingSystemService.getDataSetMapByDetailCode(DetailCode.GENDER.code, null, false);


        for (RequestListInfoVO requestInfoVO : requestList) {

            RequestListInfo requestInfo = new RequestListInfo();

            BeanUtils.copyProperties(requestInfoVO, requestInfo);

            if (ObjectUtil.isNotEmpty(requestInfoVO.getCustomerSoid())) {
                //查询患者
                List<String> coustomerSoids = new ArrayList<>();
                coustomerSoids.add(requestInfoVO.getCustomerSoid().toString());
//                RespBody<List<PatientInfoVo>> personsByCoustomerSoids = personOperationApi.getPersonsByCoustomerSoids(coustomerSoids);
                PersonInfoConditionVo personInfoConditionVo = new PersonInfoConditionVo();
                personInfoConditionVo.setCustomerSoIds(coustomerSoids);
                RespBody<List<PatientInfoVo>> personsByCoustomerSoids = personOperationApi.getPersonInfos(personInfoConditionVo);
                if (ObjectUtils.isNotEmpty(personsByCoustomerSoids.getData())) {

                    PatientInfoVo patientInfoVo = personsByCoustomerSoids.getData().get(0);

                    if (ObjectUtil.isNotEmpty(patientInfoVo)) {
                        PatientInfoVo personInfo = patientInfoVo;
                        BeanUtils.copyProperties(personInfo, requestInfo);
                    }

                }
            }

            //获取登记单信息及检查表信息
            List<ApntRegistrationForm> registrationFormByrequestSoid = getApntRegistrationForms(requestInfo.getRequestSoid());


            requestInfo.setApntRegistrationFormByrequestSoid(registrationFormByrequestSoid);
            //开单科室
            if (null != requestInfo.getRequestDept()) {
                //获取检查科室名
                requestInfo.setRequestDeptName(getBusinessUnitName(requestInfo.getRequestDept()));
            }
            //加急名称
            if (null != requestInfo.getEmergencySign() && emergencysignMap != null) {
                requestInfo.setEmergencySignName(emergencysignMap.get(Long.parseLong(requestInfo.getEmergencySign().toString())));
            }
            //年龄
            if (null != requestInfo.getBirthDate()) {
                int age = DataCenterDateUtil.getAgeByBirth(requestInfo.getBirthDate());
                requestInfo.setAge(age);
            }

            //性别
            if (null != requestInfo.getGenderCode() && genderMap != null) {
                requestInfo.setGender(genderMap.get(Long.parseLong(requestInfo.getGenderCode().toString())));
            }
            //场景名称
            if (null != requestInfo.getVisitScenceCode() && seeTheSceneMap != null) {
                requestInfo.setVisitScence(seeTheSceneMap.get(Long.parseLong(requestInfo.getVisitScenceCode().toString())));
            }
            //申请单状态
            if (null != requestInfo.getRequestStatus() && requestStatusMap != null) {
//                requestInfo.setRequestStatusName(mdmService.getDataSetName(requestInfo.getRequestStatus()));
                requestInfo.setRequestStatusName(requestStatusMap.get(Long.parseLong(requestInfo.getRequestStatus().toString())));
            }


            if (null != requestInfoVO.getRequestServiceInfoList()) {
                for (com.mida.bms.requestform.request.RequestServiceInfo requestServiceInfo : requestInfoVO.getRequestServiceInfoList()) {
                    //检查类型
                    if (null != requestServiceInfo.getExamType() && examTypeMap != null) {
//                        requestServiceInfo.setExamTypeName(mdmService.getDataSetName(requestServiceInfo.getExamType()));
                        requestServiceInfo.setExamTypeName(examTypeMap.get(Long.parseLong(requestServiceInfo.getExamType().toString())));
                    }
                    if (null != requestServiceInfo.getRequestExamPartsInfoList()) {
                        for (com.mida.bms.requestform.request.RequestExamPartsInfo requestExamPartsInfo : requestServiceInfo.getRequestExamPartsInfoList()) {
                            //部位
                            if (null != requestExamPartsInfo.getExamParts() && examPartsMap != null) {
//                                BigDecimal examParts = requestExamPartsInfo.getExamParts();
//                                String dataSetName = mdmService.getDataSetName(requestExamPartsInfo.getExamParts());
//                                requestExamPartsInfo.setExamPartName(mdmService.getDataSetName(requestExamPartsInfo.getExamParts()));
                                requestExamPartsInfo.setExamPartName(examPartsMap.get(Long.parseLong(requestExamPartsInfo.getExamParts().toString())));
                            }
                        }
                    }
                }
            }


            List<RequestServiceInfo> RequestServiceInfoList = new ArrayList<>();
            requestInfoVO.getRequestServiceInfoList().stream().forEach(requestServiceInfoList -> {
                RequestServiceInfo requestServiceInfo = new RequestServiceInfo();
                BeanUtils.copyProperties(requestServiceInfoList, requestServiceInfo);
                RequestServiceInfoList.add(requestServiceInfo);


                List<RequestExamPartsInfo> requestExamPartsInfoList = new ArrayList<>();
                requestServiceInfoList.getRequestExamPartsInfoList().stream().forEach(requestExamPartsInfo -> {
                    RequestExamPartsInfo requestExamPartsInfovo = new RequestExamPartsInfo();
                    BeanUtils.copyProperties(requestExamPartsInfo, requestExamPartsInfovo);
                    requestExamPartsInfoList.add(requestExamPartsInfovo);
                });
                requestServiceInfo.setRequestExamPartsInfoList(requestExamPartsInfoList);
            });

            requestInfo.setRequestServiceInfoList(RequestServiceInfoList);


            requestListInfoList.add(requestInfo);

        }
        Page<RequestListInfo> requestListInfoPage = new Page<>();
        BeanUtils.copyProperties(requestListInfoPage, requestListInfoRes);
        requestListInfoPage.setRecords(requestListInfoList);

        stopWatch.stop();
        log.info("申请单查询end=======================================" + stopWatch.getTime() + "ms");
        return requestListInfoPage;
    }

    /**
     * 获取登记单信息及检查表信息
     * @param requestSoid
     * @return
     */
    @NotNull
    @Override
    public List<ApntRegistrationForm> getApntRegistrationForms(BigDecimal requestSoid) {
        List<ApntRegistrationFormVO> apntRegistrationFormByrequestSoid = registerBmsApi.getApntRegistrationFormByrequestSoid(requestSoid);

        List<ApntRegistrationForm> registrationFormByrequestSoid = new ArrayList<>();

        //上机号
        apntRegistrationFormByrequestSoid.stream().forEach(item -> {
            ApntRegistrationForm apntRegistrationForm = new ApntRegistrationForm();
            BeanUtils.copyProperties(item, apntRegistrationForm);
            ApntOperateVO apntOperateByRegistrationFormSoid = examBmsApi.getApntOperateByRegistrationFormSoid(apntRegistrationForm.getRegistrationFormSoid());
            if (ObjectUtil.isNotEmpty(apntOperateByRegistrationFormSoid)) {
                if (ObjectUtils.isNotEmpty(apntOperateByRegistrationFormSoid.getExaminationVisitSoid())) {
                    apntRegistrationForm.setExaminationVisitSoid(new BigDecimal(apntOperateByRegistrationFormSoid.getExaminationVisitSoid()));
                }
                if (ObjectUtils.isNotEmpty(apntOperateByRegistrationFormSoid.getOperatorSoid())) {
                    apntRegistrationForm.setOperatorSoid(apntOperateByRegistrationFormSoid.getOperatorSoid());
                }
                registrationFormByrequestSoid.add(apntRegistrationForm);
            }

        });
        return registrationFormByrequestSoid;
    }

    /**
     * 批量获取登记单信息及其检查单信息并封装成map
     * @param requestSoids
     * @return
     */
    @NotNull
    @Override
    public HashMap<BigDecimal, List<ApntRegistrationForm>> getRequestSoidApntRegistrationFormsMap(List<BigDecimal> requestSoids) {
        HashMap<BigDecimal, List<ApntRegistrationForm>> res = new HashMap<>();
        Map<BigDecimal, List<ApntRegistrationFormVO>> apntRegistrationFormMap = registerBmsApi.getApntRegistrationFormByrequestSoidList(requestSoids);
        if (ObjectUtil.isEmpty(apntRegistrationFormMap)) {
            return res;
        }
        Set<BigDecimal> registrationFormSoidSet = apntRegistrationFormMap.values().stream().flatMap(a -> a.stream().map(ApntRegistrationFormVO::getRegistrationFormSoid)).collect(Collectors.toSet());
        List<ApntOperateVO> apntOperateByRegistrationFormSoidList = examBmsApi.getApntOperateByRegistrationFormSoidList(new ArrayList<>(registrationFormSoidSet));
        if (ObjectUtil.isEmpty(apntOperateByRegistrationFormSoidList)) {
            return res;
        }
        Map<BigDecimal, List<ApntOperateVO>> examInfoMap = apntOperateByRegistrationFormSoidList.stream().filter(ObjectUtil::isNotEmpty).collect(Collectors.groupingBy(ApntOperateVO::getRegistrationFormSoid));

        apntRegistrationFormMap.keySet().stream().filter(ObjectUtil::isNotEmpty)
                .forEach(requestSoid -> {
                    List<ApntRegistrationForm> registrationFormByrequestSoid = new ArrayList<>();
                    List<ApntRegistrationFormVO> apntRegistrationFormVOS = apntRegistrationFormMap.get(requestSoid);
                    apntRegistrationFormVOS.stream().filter(ObjectUtil::isNotEmpty).filter(a -> ObjectUtil.isNotEmpty(a.getRegistrationFormSoid()))
                            .forEach(apntRegistrationFormVO -> {
                                List<ApntOperateVO> apntOperateVOS = examInfoMap.get(apntRegistrationFormVO.getRegistrationFormSoid());
                                apntOperateVOS.forEach(apntOperateVO -> {
                                            ApntRegistrationForm apntRegistrationForm = new ApntRegistrationForm();
                                            BeanUtils.copyProperties(apntOperateVO, apntRegistrationForm);
                                            if (ObjectUtils.isNotEmpty(apntOperateVO.getExaminationVisitSoid())) {
                                                apntRegistrationForm.setExaminationVisitSoid(new BigDecimal(apntOperateVO.getExaminationVisitSoid()));
                                            }
                                            if (ObjectUtils.isNotEmpty(apntOperateVO.getOperatorSoid())) {
                                                apntRegistrationForm.setOperatorSoid(apntOperateVO.getOperatorSoid());
                                            }
                                            registrationFormByrequestSoid.add(apntRegistrationForm);
                                        }
                                );
                            });
                    res.put(requestSoid, registrationFormByrequestSoid);
                });
        //上机号
        return res;
    }


    /**
     * 获取检查科室名
     * @param BusinessUnitSoid
     * @return
     */
    @Override
    public String getBusinessUnitName(BigDecimal BusinessUnitSoid) {
        if (ObjectUtil.isEmpty(BusinessUnitSoid)) {
            return null;
        }
        String value = soidCacheMap.get(BusinessUnitSoid.toPlainString());
        if (StringUtils.isNotBlank(value)) {
            return value;
        }
        //查询开单科室
        if (ObjectUtils.isNotEmpty(BusinessUnitSoid)) {
            org.springframework.util.StopWatch sw6 = new StopWatch();
            sw6.start("从主数据查询开单科室耗时");
            ListResult<BusinessUnitVo> businessUnitBySoid = mdmService.findBusinessUnitBySoid(BusinessUnitSoid.longValueExact(), false);
            sw6.stop();
            if (ObjectUtils.isNotEmpty(businessUnitBySoid) && ObjectUtils.isNotEmpty(businessUnitBySoid.getData()) && ObjectUtils.isNotEmpty(businessUnitBySoid.getData().getBusinessUnitName())) {
                soidCacheMap.put(BusinessUnitSoid.toPlainString(), businessUnitBySoid.getData().getBusinessUnitName());
                return businessUnitBySoid.getData().getBusinessUnitName();
            }
        }
        return null;
    }

}
